package cz.muni.fi.pa165.soccergamesarchive.persistencelayer.daos;

import cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler;
import cz.muni.fi.pa165.soccergamesarchive.persistencelayer.entities.Goal;
import cz.muni.fi.pa165.soccergamesarchive.validators.ValidatorTest;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import static cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler.createErrorMessage;
import static cz.muni.fi.pa165.soccergamesarchive.validators.GoalValidator.validateGoal;

/**
 *
 * @author Tomas Plevko <tomasplevko@gmail.com>
 */
@Stateless
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class GoalDAOImpl implements GoalDAO {

    @PersistenceContext(unitName = "SoccerGamesArchivePersistenceUnit")
    private EntityManager em;

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    @Override
    public Goal addGoal(Goal goal) throws RuntimeException {

        int goalStatus = validateGoal(goal,
                ValidatorTest.NULL_TEST,
                ValidatorTest.CORRECT_RECORD_TEST);

        if (goalStatus != ErrorHandler.NO_ERROR) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), goalStatus));
        }

        em.persist(goal);
        return goal;
    }

    @Override
    public Goal changeGoal(Goal goal) throws RuntimeException {

        int goalStatus = validateGoal(goal, ValidatorTest.FULL_TEST);

        if (goalStatus != ErrorHandler.NO_ERROR) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), goalStatus));
        }

        return em.merge(goal);
    }

    @Override
    public void deleteGoal(Goal goal) throws RuntimeException {

        int goalStatus = validateGoal(goal,
                ValidatorTest.NULL_TEST,
                ValidatorTest.ID_TEST);
        if (goalStatus != ErrorHandler.NO_ERROR) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), goalStatus));
        }

        em.remove(em.merge(goal));
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<Goal> getAllGoals() throws RuntimeException {

        return em.createNamedQuery("Goal.getAllGoals", Goal.class)
                .getResultList();
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<Goal> getLimitedNumberOfGoals(int offset, int limit) throws
            RuntimeException {
        if (offset < 0 || limit <= 0) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return em.createNamedQuery("Goal.getAllGoals", Goal.class)
                .setFirstResult(offset).setMaxResults(limit).getResultList();
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public Goal getGoalById(Long id) throws RuntimeException {

        if (id == null || id < 1) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return em.find(Goal.class, id);
    }

}
